package com.newear;

import android.app.Application;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v4.util.ArrayMap;
import android.util.SparseArray;

import com.newear.base.threadpool.GrandCentralPool;
import com.newear.bean.CustomerInfo;
import com.newear.bean.ReportInfo;
import com.newear.constant.RequireParams;
import com.newear.constant.URLConstant;
import com.newear.datacenter.DataReuireOperate;
import com.newear.message.MessageDispatcher;
import com.newear.message.MessageType;
import com.newear.util.MyConstant;
import com.newear.util.MyLogger;
import com.newear.util.MySharedPreferences;

import java.io.File;

/**
 * 程序主入口
 */
public class MyApplication extends Application{
    private static final String TAG = "MyApplication";

    private static Context context;
    /**
     * 是否初始化了
     **/
    private static boolean inited = false;
    private static MyHandler appHandler;
    /**
     * 请求端Handler对象的Map集合
     **/
    private static ArrayMap<String, Handler> callHandlerMap;
    /**
     * 异步任务对象的Map集合
     **/
    private static ArrayMap<String, EventsAsyncTask> eventsAsyncTaskMap;
    // 顾客类，全局唯一
    public static CustomerInfo sCustomerInfo;
    //报告页面
    public static ReportInfo sReportInfo;

    @Override
    public void onCreate() {
        MyLogger.i(TAG, "onCreate begin!");
        super.onCreate();
        globalInit();
        MyLogger.i(TAG, "onCreate end!");
    }

    /**
     * 初始化方法
     */
    public void globalInit() {
        MyLogger.i(TAG, "globalInit begin!");
        if (inited) {
            return;
        }
        initContext();
        initCustomerInfo();
        //初始化Logger
        MyLogger.init(5);
        initThreadPolicy();
        callHandlerMap = new ArrayMap<>();
        eventsAsyncTaskMap = new ArrayMap<>();
        initThreadPool();
        initHandler();
        inited = true;
        initFile();
        initServer();
        MyLogger.i(TAG, "globalInit end!");
    }

    private void initCustomerInfo() {
        sCustomerInfo = new CustomerInfo();
        sCustomerInfo.customerNumber = MySharedPreferences.getInstance().getCustomerNumber(this);
    }

    private void initServer() {
        if (MyConstant.DEBUG) {
            URLConstant.changeServer(false);
        }
    }

    /**
     * 开启线程策略，用于检测ANR
     */
    private void initThreadPolicy() {
        if (MyConstant.DEBUG) {
            MyLogger.e(TAG, "initThreadPolicy");
            //开启线程模式
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
            //开启虚拟机模式
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
        }
    }

    /**
     * 创建文件，避免文件不存在
     */
    private void initFile() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                File file = new File(MyConstant.BASE_PATH);
                if (!file.exists()) {
                    file.mkdirs();
                }
            }
        }).start();
    }

    /**
     * 初始化appContext
     */
    private void initContext() {
        if (context == null) {
            context = getApplicationContext();
        }
    }

    /**
     * 初始化线程池方法
     */
    public void initThreadPool() {
        GrandCentralPool.initAll(4);
    }

    /**
     * 初始化Handler对象
     */
    private static void initHandler() {
        appHandler = new MyHandler();
    }

    /**
     * @return handler对象
     */
    public static Handler getHandler() {
        if (appHandler == null) {
            initHandler();
        }
        return appHandler;
    }

    /**
     * 处理数据请求
     *
     * @param obj 请求参数-ArrayMap<String, Object>
     */
    private static void processRequireData(Object obj) {
        MyLogger.i(TAG, "processRequireData!");

        if (obj == null) {
            return;
        }
        if (obj instanceof ArrayMap) {
            ArrayMap<String, Object> params = (ArrayMap<String, Object>) obj;
            Handler callbackHandler = (Handler) params.get(RequireParams.CALL_BACK_HANDLER);
            int dataType = (Integer) params.get(RequireParams.DATA_TYPE);
            MessageDispatcher.sendMessage(callbackHandler, MessageType.SHOW_DIALOG, dataType, null);
            String mapKey = (String) params.get(RequireParams.MAP_KEY);
            /**
             * 1.创建一个异步任务
             * 2.把回调handler和执行该操作的任务加到map中，取得结果以后，通过key来得到或移除
             */
            EventsAsyncTask eventAsyncTask = new EventsAsyncTask(new DataReuireOperate(context, appHandler, params));
            eventsAsyncTaskMap.put(mapKey, eventAsyncTask);
            callHandlerMap.put(mapKey, callbackHandler);
            //第二个eventAsyncTask为DataRequire中搞定requireOperate方法中的参数
            GrandCentralPool.executeDataAsyncTask(eventAsyncTask, eventAsyncTask);
        }
    }

    /**
     * 处理数据请求结果
     *
     * @param dataType 数据类型
     * @param obj      请求结果对象 SparseArray<Object> obj[0]-key,obj[1]-resultObj.至少要有obj[0],可以没有obj[1]
     */
    private static void processRequireDataFinished(int dataType, Object obj) {
        MyLogger.i(TAG, "processRequireDataFinished!");
        if (obj == null) {
            return;
        }
        if (obj instanceof SparseArray) {
            SparseArray<Object> result = (SparseArray<Object>) obj;
            if (result.size() > 0) {
                String key = (String) result.get(0);
                EventsAsyncTask task = eventsAsyncTaskMap.get(key);
                if (!task.isCancelled()) {
                    Handler callbackHandler = callHandlerMap.get(key);
                    if (callbackHandler != null) {
                        Object requireResultData = result.get(1);
                        //发送消息给请求端，通知处理请求数据结果，结果为obj
                        MessageDispatcher.sendMessage(callbackHandler, MessageType.REQUIRE_DATA_FINISHED, dataType, requireResultData);
                        //关闭请求等待框
                        MessageDispatcher.sendMessage(callbackHandler, MessageType.CLOSE_DIALOG, dataType, null);
                    }
                }
            }
        }
    }

    /**
     * 取消任务
     *
     * @param inputKey
     */
    private static void processRequireCancel(String inputKey) {
        EventsAsyncTask workAsyncTask = eventsAsyncTaskMap.remove(inputKey);

        try {
            if (workAsyncTask != null && !workAsyncTask.isCancelled()) {
                MyLogger.d(TAG, "----RequireCancel, will interrupt key="
                        + inputKey + ", task=" + workAsyncTask);
                workAsyncTask.cancel(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        callHandlerMap.remove(inputKey);
    }


    /**
     * Applicaiton 中的 Handler对象
     */
    private static class MyHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            try {
                switch (msg.what) {
                    //请求数据  msg.obj-ArrayMap<String, Object>
                    case MessageType.REQUIRE_DATA:
                        processRequireData(msg.obj);
                        break;
                    //请求数据完成 arg1-datyTpye;arg2-arg2;obj-请求结果对象
                    case MessageType.REQUIRE_DATA_FINISHED:
                        processRequireDataFinished(msg.arg1, msg.obj);
                        break;
                    //取消请求数据任务msg.obj-要被取消的任务key
                    case MessageType.REQUIRE_CANCEL:
                        processRequireCancel((String) msg.obj);
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 异步任务类，所有需要启动线程的操作，都走该类
     */
    private static class EventsAsyncTask extends AsyncTask<Object, Object, Object> {
        DataReuireOperate dataReuireOperate;

        public EventsAsyncTask(DataReuireOperate dataReuireOperate) {
            this.dataReuireOperate = dataReuireOperate;
        }

        @Override
        protected Object doInBackground(Object... params) {
            if (this.dataReuireOperate != null && params != null && params.length > 0 && params[0] instanceof AsyncTask) {
                this.dataReuireOperate.requireOprate((AsyncTask<Object, Object, Object>) params[0]);
            }
            return null;
        }
    }

}
